import * as gm from 'gm'
import * as fs from 'fs'
import {State} from "gm";
var imageMagick = gm.subClass({ imageMagick : true });

export interface MergeInfo {
    //3张目标文件
    pic1: string;
    pic2: string;
    pic3: string;
    //合并结果文件
    toPic: string;

    width: number;
    height: number;


    //压缩质量,默认80
    quality?: number;
    //大图是否在左边,默认true
    left?: boolean;
    //白线宽度,默认3
    lineSize?: number;
}


export class ImageGM {

    static tt() {
        imageMagick("/sslvpn.png").thumb(900, 900, "/thumb.png", 100, "center", (err: Error, stdout: string, stderr: string, cmd: string) => {
            console.error(err);
        });
    }

    /**
     * 合并3张图片
     * @param dat
     */
    static async merge(dat: MergeInfo) {
        if (dat.left === void 0)
            dat.left = true;
        if (dat.lineSize === void 0)
            dat.lineSize = 3;

        if (dat.quality === void 0)
            dat.quality = 80;

        let scan = 0.618;
        let scan2 = 0.382;

        let w1 = (dat.width - dat.lineSize) * scan + 1;
        let h1 = dat.height;

        let w2 = (dat.width - dat.lineSize) * scan2;
        let h2 = (dat.height - dat.lineSize) / 2;

        await ImageGM.cutPicPromise(dat.pic1, dat.pic1 + "_1.png", w1, h1, 100);
        await ImageGM.cutPicPromise(dat.pic2, dat.pic2 + "_2.png", w2, h2, 100);
        await ImageGM.cutPicPromise(dat.pic3, dat.pic3 + "_3.png", w2, h2, 100);


        let img = (imageMagick as any)(dat.width, dat.height, "#ffffffFF");
        if (dat.left) {
            img.draw(`image Over 0,0 0,0 "${dat.pic1}_1.png"`)
                .draw(`image Over ${w1 + dat.lineSize},0 0,0 "${dat.pic2}_2.png"`)
                .draw(`image Over ${w1 + dat.lineSize},${h2 + dat.lineSize} 0,0 "${dat.pic3}_3.png"`)
        }
        else {
            img.draw(`image Over ${w2 + dat.lineSize},0 0,0 "${dat.pic1}_1.png"`)
                .draw(`image Over 0,0 0,0 "${dat.pic2}_2.png"`)
                .draw(`image Over 0,${h2 + dat.lineSize} 0,0 "${dat.pic3}_3.png"`)
        }

        img.quality(dat.quality);

        await ImageGM.writePicPromise(img, dat.toPic);
        fs.unlink(dat.pic1 + "_1.png", err => {
        });
        fs.unlink(dat.pic2 + "_2.png", err => {
        });
        fs.unlink(dat.pic3 + "_3.png", err => {
        });
    }


    static cutPic(from: string, to: string, w: number, h: number, quality: number, res?: (err: Error) => void, align?: 'topleft'|'center') {
        if (align) {
            imageMagick(from).autoOrient().thumb(w, h, to, quality, align, (err: Error, stdout: string, stderr: string, cmd: string) => {
                if (res)
                    res(err);
            });
        }
        else {
            imageMagick(from).autoOrient().thumb(w, h, to, quality, (err: Error, stdout: string, stderr: string, cmd: string) => {
                if (res)
                    res(err);
            });
        }
        // imageMagick(from).thumb((err, size) => {
        //     if (err) {
        //         res(err);
        //         return;
        //     }
        //     let toScan = w / h;
        //     let fromScan = size.width / size.height;
        //
        //     let toImg = imageMagick(from).autoOrient();
        //     if (fromScan > toScan) {
        //         let newWidth = size.height * toScan;
        //         toImg.crop(newWidth, size.height, (size.width - newWidth) / 2, 0)
        //
        //     }
        //     else {
        //         let newHeight = size.width / toScan;
        //         toImg.crop(size.width, newHeight, 0, (size.height - newHeight) / 2)
        //     }
        //
        //     toImg.resize(w, h)
        //
        //         .write(to, (err: Error, stdout: string, stderr: string, cmd: string) => {
        //             res(err);
        //         })
        //
        // });
    }

    static resizePic(from: string, to: string, w: number, h: number, quality: number, option?: '%'|'<'|'>'): Promise<void> {
        return new Promise<void>((reso, reject) => {
            imageMagick(from).autoOrient().resize(w, h, option).quality(quality).write(to, (err: Error, stdout: string, stderr: string, cmd: string) => {
                if (err)
                    reject(err);
                else
                    reso();

            });
        });
    }

    static cutPicPromise(from: string, to: string, w: number, h: number, quality: number, align?: 'topleft'|'center'): Promise<void> {
        return new Promise<void>((reso, reject) => {
            ImageGM.cutPic(from, to, w, h, quality, err => {
                if (err)
                    reject(err);
                else
                    reso();
            }, align);
        });
    }

    static writePicPromise(State: State, toPic: string): Promise<void> {
        return new Promise<void>((reso, reject) => {
            State.write(toPic, (err, stdout, stderr, cmd) => {
                if (err) {
                    reject(err);
                }
                else {
                    reso();
                }
            });
        });
    }

}